﻿//------------------------------------------------------------------------------
// <copyright file="Program.cs" company="Microsoft">
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// </copyright>
//------------------------------------------------------------------------------

namespace Rpc.Client.TestApp
{
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Net;
    using System.Runtime.InteropServices;
    using System.Runtime.Serialization.Json;
    using System.Text;
    using System.Threading.Tasks;
    using Microsoft.Internal.GamesTest.Rpc.Client;

    /// <summary>
    /// Entry-point for the test app program.
    /// </summary>
    public class Program
    {
        /// <summary>
        /// Entry-point for the test app program.
        /// </summary>
        /// <param name="args">Command-line arguments.</param>
        public static void Main(string[] args)
        {
            try
            {
                string userInput = string.Empty;

                IPAddress personalConsoleAddress = IPAddress.Parse("127.0.0.1");

                using (RpcChannel channel = new RpcChannel(personalConsoleAddress))
                {
                    do
                    {
                        if (string.IsNullOrEmpty(userInput) || userInput == "r")
                        {
                            int numRetries = 0;
                            const int MaxRetries = 60;
                            while (numRetries < MaxRetries)
                            {
                                try
                                {
                                    if (!channel.IsConnected)
                                    {
                                        channel.Connect();
                                        channel.Subscribe(
                                            "SampleTestEvent", 
                                            (sender, eventArgs) =>
                                            {
                                                Console.WriteLine(eventArgs.Archive.GetNamedValue<string>("result"));
                                            });
                                    }

                                    break;
                                }
                                catch (RpcException)
                                {
                                    ++numRetries;
                                }
                            }

                            if (!channel.IsConnected)
                            {
                                throw new InitializationFailedException("Failed to connect to RpcServer.");
                            }

                            channel.OperationTimeout = TimeSpan.FromSeconds(25.0);

                            RpcArchive inputArchive = new RpcArchive();

                            inputArchive.SetNamedValue("operand1", 178UL);
                            inputArchive.SetNamedValue("operand2", 48L);

                            RpcArchive outputArchive = channel.InvokeRemoteMethod("OutputNoInput", inputArchive);

                            long result = outputArchive.GetNamedValue<long>("result");

                            Console.WriteLine("result is: " + result);
                        }

                        Console.WriteLine("What do you want to do?:");
                        Console.WriteLine("(D): Disconnect");
                        Console.WriteLine("(C): Connect");
                        Console.WriteLine("(R): Send another request");
                        Console.WriteLine("(Q): Quit");
                        userInput = Console.ReadLine().ToLower();

                        switch (userInput)
                        {
                            case "d":
                                channel.Disconnect();
                                break;
                            case "c":
                                channel.Connect();
                                break;
                        }
                    }
                    while (userInput != "q");
                }
            }
            catch (RpcException ex)
            {
                Console.WriteLine(ex.ToString());
            }
            catch (ExternalException ex)
            {
                Console.WriteLine(ex.ToString());
            }
            catch (TimeoutException ex)
            {
                Console.WriteLine(ex.ToString());
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }
    }
}
